package main

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"gitee.com/z1gotool/z1cnf/yaml2struct/yaml2go"
)

// https://github.com/Icemap/yaml2go-cli
// https://github.com/PrasadG193/yaml2go

const (
	// StupidYaml2GoStructName yaml2go library use it as root struct name
	StupidYaml2GoStructName = "Yaml2Go"

	// packageModel
	packageModel = "package %s\n\n"
)

func StructReplace(structContent, structName, packageName string) string {
	result := strings.ReplaceAll(structContent, StupidYaml2GoStructName, structName)
	return fmt.Sprintf(packageModel, packageName) + result
}

func main() {
	var (
		inputFile   *string
		outputFile  *string
		structName  *string
		packageName *string
	)

	pwdDir, modDir, err := FindGoModDir()

	tmp4 := `z1cnf2struct`
	packageName = &tmp4
	tmp := filepath.Join(pwdDir, `config`, `config_template.yaml`)
	inputFile = &tmp
	tmp2 := filepath.Join(modDir, `internal`, *packageName, *packageName+`.go`)
	outputFile = &tmp2
	tmp3 := `Z1cnf2struct`
	structName = &tmp3

	// log.Println(pwdDir, modDir, err)
	// log.Println(*inputFile, *outputFile, *packageName, *structName)

	baFile, err := os.ReadFile(*inputFile)
	if err != nil {
		panic(err)
	}

	y2g := yaml2go.New()
	strStruct, err := y2g.Convert(StupidYaml2GoStructName, baFile)
	if err != nil {
		panic(err)
	}

	os.MkdirAll(filepath.Dir(*outputFile), 0644)

	strStruct = StructReplace(strStruct, *structName, *packageName)
	err = os.WriteFile(*outputFile, []byte(strStruct), 0644)
	if err != nil {
		panic(err)
	}

	// adapter for unix
	err = os.Chmod(*outputFile, 0644)
	if err != nil {
		panic(err)
	}

	{
		// 打开文件，如果不存在则创建，并以追加模式写入
		file, err := os.OpenFile(*outputFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
		if err != nil {
			panic(err)
		}
		defer file.Close()

		// 追加字符串到文件末尾
		_, err = file.WriteString("var Z1cnf2structInstance = &Z1cnf2struct{}\n")
		if err != nil {
			panic(err)
		}
	}

}

// FindGoModDir 查找 go.mod 文件所在目录
func FindGoModDir() (pwdDir, modDir string, err error) {
	// 获取当前工作目录
	dir, err := os.Getwd()
	if err != nil {
		err = fmt.Errorf("获取当前工作目录失败: %v", err)
		return
	}

	pwdDir = dir
	modDir, err = getModuleAbsolutePath(`gitee.com/z1gotool/z1cnf`)

	return
}

func getModuleAbsolutePath(moduleName string) (string, error) {
	cmd := exec.Command("go", "list", "-m", "-f", "{{.Dir}}", moduleName)
	output, err := cmd.Output()
	if err != nil {
		return "", err
	}
	return strings.TrimSpace(string(output)), nil
}
